﻿//using easyar;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace BToolkit
{
    public class CloudRecognizer : MonoBehaviour
    {
        //public ARSession Session;
        public ARVideoPlayer videoPlayerPrefab;
        public BtnCloseARVideo btnCloseARVideo;
        public bool UseOfflineCache = false;
        public string OfflineCachePath;
        public bool showLogInfo = false;

        public static CloudRecognizer instance;

        //private CloudRecognizerFrameFilter cloudRecognizerFrameFilter;
        //private ImageTrackerFrameFilter trackerFrameFilter;
        private List<GameObject> targetObjs = new List<GameObject>();
        private List<string> loadedCloudTargetUids = new List<string>();
        //private Optional<CloudStatus> cloudStatus;
        private int cachedTargetCount;

        private void Awake()
        {
            instance = this;

            Camera.main.nearClipPlane = 0.01f;

            btnCloseARVideo.gameObject.SetActive(false);

            //trackerFrameFilter = Session.GetComponentInChildren<ImageTrackerFrameFilter>();
            //cloudRecognizerFrameFilter = Session.GetComponentInChildren<CloudRecognizerFrameFilter>();

            if (UseOfflineCache)
            {
                if (string.IsNullOrEmpty(OfflineCachePath))
                {
                    OfflineCachePath = Application.persistentDataPath + "/CloudRecognizerSample";
                }
                if (!Directory.Exists(OfflineCachePath))
                {
                    Directory.CreateDirectory(OfflineCachePath);
                }
                if (Directory.Exists(OfflineCachePath))
                {
                    var targetFiles = Directory.GetFiles(OfflineCachePath);
                    foreach (var file in targetFiles)
                    {
                        if (Path.GetExtension(file) == ".etd")
                        {
                            //LoadOfflineTarget(file);
                        }
                    }
                }
            }

            /*
            cloudRecognizerFrameFilter.CloudUpdate += (status, targets) =>
            {
                if (cloudStatus != status)
                {
                    Debug.LogFormat("Cloud status changed: {0} with {1} targets", status, targets.Count);
                    cloudStatus = status;
                }

                foreach (var target in targets)
                {
                    var uid = target.uid();
                    if (loadedCloudTargetUids.Contains(uid))
                    {
                        continue;
                    }

                    LoadCloudTarget(target.Clone() as ImageTarget);
                }
            };
            */
        }

        private void OnGUI()
        {
            if (showLogInfo)
            {
                /*
                GUILayout.Label("Cloud Recognizing: " + (cloudRecognizerFrameFilter && cloudRecognizerFrameFilter.enabled ? "On" : "Off"));
                GUILayout.Label("CloudStatus: " + (cloudRecognizerFrameFilter && cloudRecognizerFrameFilter.enabled ? cloudStatus.ToString() : "-"));
                GUILayout.Label("CachedTargets: " + cachedTargetCount);
                GUILayout.Label("LoadedTargets: " + loadedCloudTargetUids.Count);
                */
            }
        }

        private void OnDestroy()
        {
            foreach (var obj in targetObjs)
            {
                Destroy(obj);
            }
        }

        public void ClearAll()
        {
            if (Directory.Exists(OfflineCachePath))
            {
                var targetFiles = Directory.GetFiles(OfflineCachePath);
                foreach (var file in targetFiles)
                {
                    if (Path.GetExtension(file) == ".etd")
                    {
                        File.Delete(file);
                    }
                }
            }
            foreach (var obj in targetObjs)
            {
                Destroy(obj);
            }
            targetObjs.Clear();
            loadedCloudTargetUids.Clear();
            cachedTargetCount = 0;
        }
        /*
        private void LoadCloudTarget(ImageTarget target)
        {
            var uid = target.uid();
            loadedCloudTargetUids.Add(uid);
            var go = new GameObject(uid);
            targetObjs.Add(go);
            var targetController = go.AddComponent<ImageTargetController>();
            targetController.SourceType = ImageTargetController.DataSource.Target;
            targetController.TargetSource = target;
            LoadTargetIntoTracker(targetController);

            targetController.TargetLoad += (loadedTarget, result) =>
            {
                if (!result)
                {
                    Debug.LogErrorFormat("target {0} load failed", uid);
                    return;
                }
                AddVideoOnTarget(targetController);
            };

            if (UseOfflineCache && Directory.Exists(OfflineCachePath))
            {
                if (target.save(OfflineCachePath + "/" + target.uid() + ".etd"))
                {
                    cachedTargetCount++;
                }
            }
        }

        private void LoadOfflineTarget(string file)
        {
            var go = new GameObject(Path.GetFileNameWithoutExtension(file) + "-offline");
            targetObjs.Add(go);
            var targetController = go.AddComponent<ImageTargetController>();
            targetController.SourceType = ImageTargetController.DataSource.TargetDataFile;
            targetController.TargetDataFileSource.PathType = PathType.Absolute;
            targetController.TargetDataFileSource.Path = file;
            LoadTargetIntoTracker(targetController);

            targetController.TargetLoad += (loadedTarget, result) =>
            {
                if (!result)
                {
                    Debug.LogErrorFormat("target data {0} load failed", file);
                    return;
                }
                loadedCloudTargetUids.Add(loadedTarget.uid());
                cachedTargetCount++;
                AddVideoOnTarget(targetController);
            };
        }

        private void LoadTargetIntoTracker(ImageTargetController controller)
        {
            controller.Tracker = trackerFrameFilter;
            controller.TargetFound += () =>
            {
                cloudRecognizerFrameFilter.enabled = false;
            };
            controller.TargetLost += () =>
            {
                cloudRecognizerFrameFilter.enabled = true;
            };
        }

        private void AddVideoOnTarget(ImageTargetController controller)
        {
            CloudServerAPI.Instance.LoadTargetInfo(controller.TargetSource.uid(), (ARVideoInfo info) =>
            {
                if (info != null)
                {
                    ARVideoPlayer player = Instantiate(videoPlayerPrefab);
                    player.transform.SetParent(controller.transform, false);
                    info.aspectRatio = controller.TargetSource.aspectRatio();
                    player.Play(info);
                    OffCardController.AllTargetAsCameraChildrenSwapToTracking();
                }
            });
        }
        */
    }
}
